﻿using System;

namespace CSharp入门_控制台项目
{
	class Program
	{
		private const int w = 50;
		private const int h = 30;
		private const int ROW = 20;
		private const int COL = 46;
		private const int ADD_HP = 1;
		private const int ADD_ATTK = 1;
		private const int ADD_DEF = 1;
		private static int php_ = 15;
		private static int pattk_ = 4;
		private static int pdef_ = 0;
		private static int level = 1;
		private static int sceneID = 0;
		private static string game_over_info = "";
		static void menu(int pos = 0) {
			Console.SetCursorPosition(w / 2 - 5, 3);
			Console.ForegroundColor = ConsoleColor.White;
			Console.WriteLine("勇者斗恶龙");
			Console.SetCursorPosition(w / 2 - 5, 5);
			Console.ForegroundColor = pos == 0 ? ConsoleColor.Red : ConsoleColor.White;
			Console.WriteLine("开始游戏");
			Console.SetCursorPosition(w / 2 - 5, 6);
			Console.ForegroundColor = pos == 1 ? ConsoleColor.Red : ConsoleColor.White;
			Console.WriteLine("退出游戏");
			if (pos == 0)
			{
				Console.SetCursorPosition(w / 2 - 5 - 2, 5);
				Console.ForegroundColor = ConsoleColor.Red;
				Console.Write("->");
				Console.SetCursorPosition(w / 2 - 5 - 2, 6);
				Console.Write("  ");
			}
			else
			{
				Console.SetCursorPosition(w / 2 - 5 - 2, 6);
				Console.ForegroundColor = ConsoleColor.Red;
				Console.Write("->");
				Console.SetCursorPosition(w / 2 - 5 - 2, 5);
				Console.Write("  ");
			}
			

			Console.SetCursorPosition(w / 2 - 10, 8);
			Console.ForegroundColor = ConsoleColor.Yellow;
			Console.WriteLine("---按 f/F 键确认---");
			Console.SetCursorPosition(w / 2 - 15, 10);
			Console.WriteLine("---输入没反应？记得切换输入法---");
			Console.SetCursorPosition(w / 2 - 10, 11);
			Console.WriteLine("---w/a/s/d进行移动---");

		}
		static void init(int w, int h)
		{
			Console.SetWindowSize(w, h);
			Console.SetBufferSize(w, h);
			Console.CursorVisible = false;

			// 设置窗口和缓冲区大小
			//Console.SetWindowSize(48, 21);
			//Console.SetBufferSize(48, 21);
			//Console.BackgroundColor = ConsoleColor.Black;
			//Console.ForegroundColor = ConsoleColor.White;
			//Console.Clear();
			//Console.CursorVisible = false;
		}
		static void draw_map()
		{	
			Console.ForegroundColor = ConsoleColor.Red;
			
			for (int i = 0; i < w; i += 2)
			{
				Console.SetCursorPosition(i, 0);
				Console.Write("墙");
				Console.SetCursorPosition(i, h - 5 - 6);
				Console.Write("墙");
				Console.SetCursorPosition(i, h - 5);
				Console.Write("墙");
			}

			for (int i = 0; i <= h - 5; i++)
			{
				Console.SetCursorPosition(0, i);
				Console.Write("墙");
				Console.SetCursorPosition(w - 2, i);
				Console.Write("墙");
			}
			Console.ForegroundColor = ConsoleColor.White;

		}
		static void clear_obj(int x, int y)
		{
			Console.SetCursorPosition(x, y);
			Console.Write(" ");
		}
		static void draw(int x, int y, string icon, ConsoleColor color)
		{
			Console.ForegroundColor = color;
			Console.SetCursorPosition(x, y);
			Console.Write(icon);
		}
		static void draw_player(int x, int y, string icon, ConsoleColor color)
		{
			draw(x, y, icon, color);
		}
		static void draw_enemy(int x, int y, string icon, ConsoleColor color)
		{
			draw(x, y, icon, color);
		}
		static void game_scene()
		{
			Console.Clear();
			draw_map();
		}
		static bool is_crash(int x1, int y1, int x2, int y2)
		{
			if (x1 == x2 && y1 == y2) return true;
			if (y1 == y2 && (int)Math.Abs(x1 - x2) == 1) return true;
			return false;
		}
		static void draw_player_info(int hp, int attk1, int attk2, int def)
		{
			Console.ForegroundColor = ConsoleColor.White;

			Console.SetCursorPosition(3, h - 4);
			Console.Write("                                          ");
			Console.SetCursorPosition(3, h - 4);
			Console.Write("玩家: level: {0}, PH {1}, ATTK {2}~{3}, DEF {4}",
				level, hp, attk1, attk2, def);
		}
		static bool battle(int pattk, int php, int pdef, int eattk, int ehp, int edef)
		{
			Console.SetCursorPosition(3, 15);
			Console.ForegroundColor = ConsoleColor.DarkCyan;
			Console.WriteLine("战斗开始，按j/J键继续");
			
			while (true)
			{
				int key = Console.ReadKey(true).KeyChar;
				
				switch (key)
				{
					case 'j':
					case 'J':
						{
							Random r = new Random();
							pattk = r.Next(pattk_, pattk_ + 3);
							int damage = pattk > edef ? pattk - edef : 0;
							ehp = ehp - damage;
							if (ehp < 0) ehp = 0;
							Console.SetCursorPosition(3, 16);
							Console.ForegroundColor = ConsoleColor.Green;
							Console.WriteLine("                                      ");
							Console.SetCursorPosition(3, 16);
							Console.WriteLine("你对boss造成{0}点伤害，boss剩余血量为{1}", damage, ehp);
							if (ehp <= 0)
							{
								Console.SetCursorPosition(3, 17);
								Console.ForegroundColor = ConsoleColor.Green;
								Console.WriteLine("                                      ");
								Console.SetCursorPosition(3, 17);
								Console.ForegroundColor = ConsoleColor.Red;
								Console.WriteLine("你战胜了boss！！！，即将返回主界面");
								return false;
							}

							eattk = r.Next(6, 13);
							damage = eattk > pdef ? eattk - pdef : 0;
							php = php - damage;
							if (php < 0) php = 0;
							Console.SetCursorPosition(3, 17);
							Console.ForegroundColor = ConsoleColor.Yellow;
							Console.WriteLine("                                       ");
							Console.SetCursorPosition(3, 17);
							Console.WriteLine("boss对你造成{0}点伤害，你剩余血量为{1}", damage, php);
							draw_player_info(php, pattk_, pattk_ + 3, pdef);
							if (php <= 0)
							{
								Console.SetCursorPosition(3, 16);
								Console.ForegroundColor = ConsoleColor.Green;
								Console.WriteLine("                                       ");
								Console.SetCursorPosition(3, 16);
								Console.ForegroundColor = ConsoleColor.Red;
								Console.WriteLine("你被boss杀死了，勇士，下次再来挑战");
								return true;
							}
						}
						break;
				}
				
			}

			Console.SetCursorPosition(3, 18);
			Console.ForegroundColor = ConsoleColor.Red;
			Console.WriteLine("战斗结束");
		}
		static void play_game()
		{
			game_scene();
			Random rr = new Random();
			int px = rr.Next(2, COL - 3);
			int py = rr.Next(1, ROW / 2 - 2);
			int pattk = rr.Next(pattk_, pattk_ + 3);
			int php = php_;
			int pdef = pdef_;
			ConsoleColor pcolor = ConsoleColor.Green;
			string picon = "我";

			int ex = 8;
			int ey = 8;
			do
			{
				ex = rr.Next(2, COL - 3);
				ey = rr.Next(1, ROW / 2 - 2);
			} while (ex == px && ey == py);


			int eattk = rr.Next(5, 13);
			int ehp = 40;
			int edef = 5;
			ConsoleColor ecolor = ConsoleColor.Yellow;
			string eicon = "龙";
			draw_player_info(php, pattk_, pattk_ + 3, pdef);
			int princess_x = 9;
			int princess_y = 9;
			string princess_icon = "主";
			ConsoleColor princess_color = ConsoleColor.Blue;

			bool is_over = false;
			bool is_fight = false;
			Console.ForegroundColor = ConsoleColor.Yellow;
			Console.SetCursorPosition(3, h - 10);
			Console.WriteLine("击败巨龙，解救公主。靠近并按下j/J战斗");
			while (true)
			{
				//Console.ForegroundColor = ConsoleColor.White;
				//Console.SetCursorPosition(3, Console.BufferHeight - 1);
				//Console.Write("debug: 当前坐标:[{0},{1}] ", px, py);
				#region boss
				if (ehp > 0)
				{
					draw_enemy(ex, ey, eicon, ecolor);
				}
				else
				{
					draw(princess_x, princess_y, princess_icon, princess_color);
				}
				#endregion
				#region player
				draw_player(px, py, picon, pcolor);
				int key = Console.ReadKey(true).KeyChar;
				clear_obj(px, py);
				#endregion
				
				if (is_fight)
				{
					if (key != 'j' && key != 'J') continue; 
					// 战斗逻辑
					if (php <= 0)
					{
						is_over = true;
						is_fight = false;
						sceneID = 2;
						game_over_info = "挑战失败结局2";
					}
					else if (ehp <= 0)
					{
						clear_obj(ex, ey);
						Console.ForegroundColor = ConsoleColor.Green;
						Console.SetCursorPosition(3, h - 10);
						Console.WriteLine("                                      ");
						Console.SetCursorPosition(3, h - 9);
						Console.WriteLine("                                      ");
						Console.SetCursorPosition(3, h - 8);
						Console.WriteLine("                                      ");
						Console.SetCursorPosition(3, h - 7);
						Console.WriteLine("                                      ");
						Console.ForegroundColor = ConsoleColor.Yellow;
						Console.SetCursorPosition(3, h - 10);
						Console.WriteLine("靠近并按下j/J解救公主");
						is_fight = false;
					}
					else
					{
						Random r = new Random();
						pattk = r.Next(pattk_, pattk_ + 3);
						int damage = pattk > edef ? pattk - edef : 0;
						ehp = ehp - damage;
						if (ehp < 0) ehp = 0;
						Console.SetCursorPosition(3, h - 9);
						Console.ForegroundColor = ConsoleColor.Green;
						Console.WriteLine("                                      ");
						Console.SetCursorPosition(3, h - 9);
						Console.WriteLine("你对boss造成{0}点伤害，boss剩余血量为{1}", damage, ehp);
						
						
						Console.SetCursorPosition(3, h - 8);
						Console.WriteLine("                                       ");
						if (ehp > 0)
						{
							eattk = r.Next(6, 13);
							damage = eattk > pdef ? eattk - pdef : 0;
							php = php - damage;
							if (php < 0) php = 0;
							Console.ForegroundColor = ConsoleColor.Yellow;
							Console.SetCursorPosition(3, h - 8);
							Console.WriteLine("boss对你造成{0}点伤害，你剩余血量为{1}", damage, php);
							if (php <= 0)
							{
								Console.SetCursorPosition(3, h - 7);
								Console.ForegroundColor = ConsoleColor.Green;
								Console.WriteLine("                                       ");
								Console.SetCursorPosition(3, h - 7);
								Console.ForegroundColor = ConsoleColor.Red;
								Console.WriteLine("你被boss杀死了，勇士，下次再来挑战");
								Console.SetCursorPosition(3, h - 10);
								Console.ForegroundColor = ConsoleColor.Yellow;
								Console.WriteLine("战斗结束，按j/J键继续");
							}
							
							draw_player_info(php, pattk_, pattk_ + 3, pdef);

						}
						else
						{
							Console.SetCursorPosition(3, h - 10);
							Console.WriteLine("                                      ");
							Console.SetCursorPosition(3, h - 8);
							Console.ForegroundColor = ConsoleColor.Green;
							Console.WriteLine("                                      ");
							Console.SetCursorPosition(3, h - 8);
							Console.WriteLine("你战胜了boss, 前去解救公主吧");
							Console.SetCursorPosition(3, h - 7);
							Console.WriteLine("                                      ");
							Console.SetCursorPosition(3, h - 7);
							Console.ForegroundColor = ConsoleColor.Yellow;
							Console.WriteLine("按下 j/J 继续");
						}
					}
				}
				else
				{
					//其他逻辑
					switch (key)
					{
						case 'w':
						case 'W':
							py -= 1;
							if (py < 1)
							{
								py = 1;
								continue;
							}
							if (ehp > 0 && is_crash(px, py, ex, ey))
							{
								py++;
							}
							if (ehp <= 0 && is_crash(px, py, princess_x, princess_y))
							{
								py++;
							}
							break;
						case 'a':
						case 'A':
							px -= 1;
							if (px < 2)
							{
								px = 2;
								continue;
							}
							if (ehp > 0 && is_crash(px, py, ex, ey))
							{
								px++;
							}
							if (ehp <= 0 && is_crash(px, py, princess_x, princess_y))
							{
								px++;
							}
							break;
						case 's':
						case 'S':
							py += 1;
							if (py > h - 12)
							{
								py = h - 12;
								continue;
							}
							if (ehp > 0 && is_crash(px, py, ex, ey))
							{
								py--;
							};
							if (ehp <= 0 && is_crash(px, py, princess_x, princess_y))
							{
								py--;
							}
							break;
						case 'd':
						case 'D':
							px += 1;
							if (px > w - 4)
							{
								px = w - 4;
								continue;
							}
							if (ehp > 0 && is_crash(px, py, ex, ey))
							{
								px--;
							}
							if (ehp <= 0 && is_crash(px, py, princess_x, princess_y))
							{
								px--;
							}
							break;
						case 'j':
						case 'J':
							if (ehp > 0 && 
								(px == ex && py - ey == 1 ||
								px == ex && ey - py == 1 ||
								py == ey && px - ex == 2 ||
								py == ey && ex - px == 2))
							{
								is_fight = true;
								Console.SetCursorPosition(3, h - 10);;
								Console.WriteLine("                                      ");
								Console.SetCursorPosition(3, h - 10);
								Console.ForegroundColor = ConsoleColor.DarkCyan;
								Console.WriteLine("战斗开始，按j/J键继续");
								Console.SetCursorPosition(3, h - 9); ;
								Console.WriteLine("                                      ");
								Console.SetCursorPosition(3, h - 9);
								Console.ForegroundColor = ConsoleColor.DarkCyan;
								Console.WriteLine("你的血量为{0}", php);
								Console.SetCursorPosition(3, h - 8); ;
								Console.WriteLine("                                      ");
								Console.SetCursorPosition(3, h - 8);
								Console.ForegroundColor = ConsoleColor.DarkCyan;
								Console.WriteLine("boss的血量为{0}", ehp);
							}
							else if (ehp <= 0 &&
								(px == princess_x && py - princess_y == 1 ||
								px == princess_x && princess_y - py == 1 ||
								py == princess_y && px - princess_x == 2 ||
								py == princess_y && princess_x - px == 2))
							{
								sceneID = 2;
								is_over = true;
								game_over_info = "英雄救美结局达成";
							}
							break;
					}
				}
				



				if (is_over)
				{
					level += 1;
					pattk_ += ADD_ATTK;
					php_ += ADD_HP;
					pdef_ += ADD_DEF;
					//Console.ForegroundColor = ConsoleColor.Blue;
					//Console.SetCursorPosition(3, h - 9);
					//Console.WriteLine("                                       ");
					//Console.SetCursorPosition(3, h - 8);
					//Console.WriteLine("                                       ");
					//Console.SetCursorPosition(3, h - 9);
					//Console.WriteLine("按下 j/J 返回主界面    ");
					//key = Console.ReadKey(true).KeyChar;
					//while (key != 'j' && key != 'J') key = Console.ReadKey(true).KeyChar;
					break;
				}
			}
		}
		static void Main(string[] args) {
			init(w, h);
			
			while (true)
			{
				switch (sceneID)
				{
					case 0:
						#region 游戏开始
						Console.Clear();
						int now_pos = 0;		
						while (true)
						{
							menu(now_pos);
							bool is_over = false;
							int key = Console.ReadKey(true).KeyChar;
							switch (key)
							{
								case 'w':
								case 'W':
									now_pos -= 1;
									if (now_pos < 0) now_pos = 1;
									break;
								case 's':
								case 'S':
									now_pos += 1;
									now_pos %= 2;
									break;
								case 'f':
								case 'F':
									switch (now_pos)
									{
										case 0:
											sceneID = 1;
											is_over = true;
											break;
										case 1:
											Environment.Exit(0);
											break;
									}
									break;
								default:

									break;
							}
							if (is_over) break;
						}
						#endregion
						break;
					case 1:
						#region 游戏战斗
						Console.Clear();
						play_game();
						#endregion
						break;
					case 2:
						#region 游戏结束
						Console.Clear();
						Console.ForegroundColor = ConsoleColor.White;
						Console.SetCursorPosition(w / 2 - 4, 3);
						Console.WriteLine("游戏结束");
						Console.SetCursorPosition(w / 2 - game_over_info.Length, 4);
						Console.WriteLine(game_over_info);
						Console.SetCursorPosition(w / 2 - 10, 9);
						Console.ForegroundColor = ConsoleColor.Yellow;
						Console.WriteLine("---按 f/F 键确认---");
						int pos = 0;
						while (true)
						{
							bool is_over = false;
							
							Console.SetCursorPosition(w / 2 - 5, 7);
							Console.ForegroundColor = pos == 0 ? ConsoleColor.Red : ConsoleColor.White;
							 Console.WriteLine("返回主界面");
							Console.SetCursorPosition(w / 2 - 4, 8);
							Console.ForegroundColor = pos == 1 ? ConsoleColor.Red : ConsoleColor.White;
							Console.WriteLine("退出游戏");
							int key = Console.ReadKey(true).KeyChar;
							switch(key)
							{
								case 'w':
								case 'W':
									pos -= 1;
									if (pos < 0)
									{
										pos = 1;
									}
									break;
								case 's':
								case 'S':
									pos += 1;
									pos %= 2;
									break;
								case 'f':
								case 'F':
									if (pos == 0)
									{
										sceneID = 0;
										is_over = true;
									}
									else
									{
										Environment.Exit(0);
									}
									break;
							}
							if (is_over) break;
						}
						#endregion
						break;
				}
			}

			
		}
	}
}
